
/*
 * @项目名称: 模板开发
 * @FilePath: /meek/src/geometry/parallelogram.js
 * @Author: 1106408264@qq.com
 * @Date: 2017-08-23T18:20:34+08:00
 * @LastEditors: kongxueyang@datatang.com
 * @LastEditTime: 2021-11-05T10:21:17+08:00
 * Copyright (c) 2018-2022
 */

/**
 * Created by zhangyong on 2017/8/23.
 */

import Geometry from './geometry'
import Polygon from './polygon'
import {distance} from '../geometry/support/geometryutil'

import {getPointInExtendedLineByDistanceFromAB} from '../geometry/support/geometryutil'

export default class Parallelogram extends Polygon {

  constructor (coordinates) {
    super(coordinates)
  }

  get geometryType () {
    return Geometry.PARALLELOGRAM
  }

  getCoordinateIndex (coord) {
    return this.getCoordinates()[0].findIndex( points =>
      points[0] === coord[0] && points[1] === coord[1]
    )
  }

  clone () {
    return new Parallelogram(this.getCoordinates())
  }

  /**
   *
   * @param coordinates
   * @returns {Array}
   */
  static getTheLastPoint (coordinates) {
    const firstPoint = coordinates[0]
    const secondPoint = coordinates[1]
    const thirdPoint = coordinates[2]

    const dx = thirdPoint[0] - secondPoint[0]
    const dy = thirdPoint[1] - secondPoint[1]

    return [firstPoint[0] + dx, firstPoint[1] + dy]
  }


  /**
   * 用于计算和更新平行四边形的顶点
   *
   * @param p 平行四边形对象
   * @param vertex 新移动的点
   * @param oldVertex 上次移动的点
   * @param dragSegment 数据对象
   * @returns {*} 返回新的点集合（3维数组）
   */
  static updateCoordinatesForModification(p, vertex, oldVertex, dragSegment, extent) {
    let dis = 0
    if (oldVertex) {
      dis = distance (oldVertex, vertex)
    }



    const oldRingsCoordinates = p.getCoordinates()

    const cachePoints = JSON.parse(JSON.stringify(oldRingsCoordinates))
    if (dis === 0) {
      return oldRingsCoordinates
    }

    const oldCoordinates = oldRingsCoordinates[0]
    const segement = dragSegment[0]
    const edgeIndex = segement.index

    let firstCoord
    let nowCood
    let otherCood

    if (edgeIndex === 0 || edgeIndex === 4) {
      firstCoord = oldCoordinates[3]
      nowCood = oldCoordinates[0]
      otherCood = oldCoordinates[1]
    } else {
      firstCoord = oldCoordinates[edgeIndex - 1]
      nowCood = oldCoordinates[edgeIndex]
      otherCood = oldCoordinates[edgeIndex + 1]
    }

    // 计算延长线上的一点
    const newCood1 = getPointInExtendedLineByDistanceFromAB(firstCoord[0],
      firstCoord[1], nowCood[0], nowCood[1], dis)

    // 计算向量
    const tempXX = nowCood[0] - firstCoord[0]
    const tempYY = nowCood[1] - firstCoord[1]
    const tempX2 = vertex[0] - oldVertex[0]
    const tempY2 = vertex[1] - oldVertex[1]

    // 使用向量的点积，来计算两个向量的方向是否一致
    // 如果 <0 则表示异向
    const direction = ( tempX2 * tempXX ) + (tempY2 * tempYY)

    const dx = newCood1[0] - nowCood[0]
    const dy = newCood1[1] - nowCood[1]
    let newCood2

    // 不同方向
    if (direction < 0) {
      newCood1[0] = nowCood[0] - dx
      newCood1[1] = nowCood[1] - dy

      newCood2 = [otherCood[0] - dx, otherCood[1] - dy]
    } else {
      newCood2 = [otherCood[0] + dx, otherCood[1] + dy]
    }


    oldCoordinates[edgeIndex] = newCood1
    oldCoordinates[edgeIndex + 1] = newCood2

    if (edgeIndex === 0) {
      oldCoordinates[4] = oldCoordinates[0]
    } else if (edgeIndex === 4 || edgeIndex === 3) {
      oldCoordinates[0] = oldCoordinates[4]
    }

    if (extent) {
      const maxX = extent[2]
      const maxY = extent[3]
      const [x11, y11] = oldCoordinates[0]
      const [x22, y22] = oldCoordinates[1]
      const [x33, y33] = oldCoordinates[2]
      const [x44, y44] = oldCoordinates[3]
      if (
        x11 < 0 ||
        y11 < 0 ||
        x22 < 0 ||
        y22 < 0 ||
        x33 < 0 ||
        y33 < 0 ||
        x44 < 0 ||
        y44 < 0 ||
        x11 > maxX ||
        y11 > maxY ||
        x22 > maxX ||
        y22 > maxY ||
        x33 > maxX ||
        y33 > maxY ||
        x44 > maxX ||
        y44 > maxY
      ) {
        return cachePoints
      }
    }



    return [oldCoordinates]
  }

  rotate(extent, mouseDownX, mouseDownY, mouseMoveX, mouseMoveY) {
    var arr = this.getCoordinates()[0];

    //四个顶点坐标(x1,y1),(x2,y2),(x3,y3),(x4,y4)
    var x1 = arr[0][0],
      y1 = arr[0][1];
    var x2 = arr[1][0],
      y2 = arr[1][1];
    var x3 = arr[2][0],
      y3 = arr[2][1];
    var x4 = arr[3][0],
      y4 = arr[3][1];
    //矩形中心点(cX,cY)
    //利用两条相交线进行求解
    var k1 = (y3 - y1) / (x3 - x1);
    var k2 = (y4 - y2) / (x4 - x2);
    var cX = (y1 - k1 * x1 + k2 * x2 - y2) / (k2 - k1);
    var cY = k1 * cX + y1 - k1 * x1;
    //鼠标第一个点(mX1,mY1)
    var mX1 = mouseDownX;
    var mY1 = mouseDownY;
    //鼠标移动点(mX2,mY2)
    var mX2 = mouseMoveX;
    var mY2 = mouseMoveY;
    //旋转角度cos(θ) = cos;sin(θ) = sin;
    //通过向量的点积进行求解
    var abx = cX - mX1;
    var aby = cY - mY1;
    var acx = cX - mX2;
    var acy = cY - mY2;
    //叉乘求sin(θ)
    var abxac = abx * acy - acx * aby;
    var model =
      Math.sqrt(abx * abx + aby * aby) * Math.sqrt(acx * acx + acy * acy);
    var sin = abxac / model;
    //点乘求cos(θ)
    var abac = abx * acx + aby * acy;
    var cos = abac / model;
    //求旋转后的四个点(x11,y11),(x22,y22),(x33,y33),(x44,y44),(x55,y55)
    var x11 = (x1 - cX) * cos - (y1 - cY) * sin + cX;
    var y11 = (x1 - cX) * sin + (y1 - cY) * cos + cY;

    var x22 = (x2 - cX) * cos - (y2 - cY) * sin + cX;
    var y22 = (x2 - cX) * sin + (y2 - cY) * cos + cY;

    var x33 = (x3 - cX) * cos - (y3 - cY) * sin + cX;
    var y33 = (x3 - cX) * sin + (y3 - cY) * cos + cY;

    var x44 = (x4 - cX) * cos - (y4 - cY) * sin + cX;
    var y44 = (x4 - cX) * sin + (y4 - cY) * cos + cY;

    var x55 = x11;
    var y55 = y11;
    var arr = [[x11, y11], [x22, y22], [x33, y33], [x44, y44], [x55, y55]];
    //this.rotateData.mousedownX = mouseMoveX;
    //this.rotateData.mousedownY = mouseMoveY;
    if (extent) {
      var maxX = extent[2];
      var maxY = extent[3];
      if (
        x11 < 0 ||
        y11 < 0 ||
        x22 < 0 ||
        y22 < 0 ||
        x33 < 0 ||
        y33 < 0 ||
        x44 < 0 ||
        y44 < 0 ||
        x11 > maxX ||
        y11 > maxY ||
        x22 > maxX ||
        y22 > maxY ||
        x33 > maxX ||
        y33 > maxY ||
        x44 > maxX ||
        y44 > maxY
      ) {
        return;
      }
    }

    this.getCoordinates()[0] = arr;
  }

}
